package org.hhf.core;

import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.locks.ReentrantReadWriteLock;

/**
 * SetRedis类实现了Redis的集合数据类型操作
 */
public class SetRedis {
    private final RedisCore core;
    private final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();

    public SetRedis(RedisCore core) {
        this.core = core;
    }

    /**
     * 获取集合，如果不存在则创建
     */
    @SuppressWarnings("unchecked")
    private Set<String> getOrCreateSet(String key) {
        Object value = core.get(key);
        if (value == null || !(value instanceof Set)) {
            Set<String> set = ConcurrentHashMap.newKeySet();
            core.put(key, set, RedisCore.DataType.SET);
            return set;
        }
        return (Set<String>) value;
    }

    /**
     * 向集合中添加元素
     */
    public Long sadd(String key, String... members) {
        lock.writeLock().lock();
        try {
            Set<String> set = getOrCreateSet(key);
            long added = 0;
            for (String member : members) {
                if (set.add(member)) {
                    added++;
                }
            }
            return added;
        } finally {
            lock.writeLock().unlock();
        }
    }

    /**
     * 从集合中移除元素
     */
    public Long srem(String key, String... members) {
        lock.writeLock().lock();
        try {
            Set<String> set = getOrCreateSet(key);
            long removed = 0;
            for (String member : members) {
                if (set.remove(member)) {
                    removed++;
                }
            }
            return removed;
        } finally {
            lock.writeLock().unlock();
        }
    }

    /**
     * 获取集合中的所有元素
     */
    public Set<String> smembers(String key) {
        lock.readLock().lock();
        try {
            Set<String> set = getOrCreateSet(key);
            return new HashSet<>(set);
        } finally {
            lock.readLock().unlock();
        }
    }

    /**
     * 集合交集
     */
    public Set<String> sinter(String... keys) {
        if (keys == null || keys.length == 0) {
            return Collections.emptySet();
        }
        
        lock.readLock().lock();
        try {
            Set<String> result = new HashSet<>(getOrCreateSet(keys[0]));
            
            // 计算交集
            for (int i = 1; i < keys.length; i++) {
                Set<String> currentSet = getOrCreateSet(keys[i]);
                result.retainAll(currentSet);
                
                // 如果结果集为空，可以提前返回
                if (result.isEmpty()) {
                    break;
                }
            }
            
            return result;
        } finally {
            lock.readLock().unlock();
        }
    }

    /**
     * 集合并集
     */
    public Set<String> sunion(String... keys) {
        if (keys == null || keys.length == 0) {
            return Collections.emptySet();
        }
        
        lock.readLock().lock();
        try {
            Set<String> result = new HashSet<>();
            
            // 计算并集
            for (String key : keys) {
                Set<String> currentSet = getOrCreateSet(key);
                result.addAll(currentSet);
            }
            
            return result;
        } finally {
            lock.readLock().unlock();
        }
    }

    /**
     * 集合差集
     */
    public Set<String> sdiff(String key, String... otherKeys) {
        lock.readLock().lock();
        try {
            Set<String> result = new HashSet<>(getOrCreateSet(key));
            
            // 计算差集
            for (String otherKey : otherKeys) {
                Set<String> otherSet = getOrCreateSet(otherKey);
                result.removeAll(otherSet);
            }
            
            return result;
        } finally {
            lock.readLock().unlock();
        }
    }

    /**
     * 检查元素是否在集合中
     */
    public Boolean sismember(String key, String member) {
        lock.readLock().lock();
        try {
            Set<String> set = getOrCreateSet(key);
            return set.contains(member);
        } finally {
            lock.readLock().unlock();
        }
    }

    /**
     * 获取集合的大小
     */
    public Long scard(String key) {
        lock.readLock().lock();
        try {
            Set<String> set = getOrCreateSet(key);
            return (long) set.size();
        } finally {
            lock.readLock().unlock();
        }
    }

    /**
     * 随机获取集合中的一个元素
     */
    public String srandmember(String key) {
        lock.readLock().lock();
        try {
            Set<String> set = getOrCreateSet(key);
            if (set.isEmpty()) {
                return null;
            }
            
            // 随机选择一个元素
            int randomIndex = new Random().nextInt(set.size());
            int i = 0;
            for (String member : set) {
                if (i == randomIndex) {
                    return member;
                }
                i++;
            }
            
            return null;
        } finally {
            lock.readLock().unlock();
        }
    }

    /**
     * 随机移除并返回集合中的一个元素
     */
    public String spop(String key) {
        lock.writeLock().lock();
        try {
            Set<String> set = getOrCreateSet(key);
            if (set.isEmpty()) {
                return null;
            }
            
            // 随机选择一个元素
            String randomMember = srandmember(key);
            if (randomMember != null) {
                set.remove(randomMember);
            }
            
            return randomMember;
        } finally {
            lock.writeLock().unlock();
        }
    }
}